using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.IO;

// 注意：同一个类可以分文件定义，C#支持部分类(partial)
public partial class TextureChannelTool : EditorWindow
{
    void CombineMesh(string savePath)
    {
        Texture2D black = new Texture2D(1, 1, TextureFormat.RGBA32, false);
        black.SetPixel(0, 0, Color.black);
        black.Apply();

        int width = 0;
        int height = 0;
        for (int i = 0; i < editorArray.Length; i++)
        {
            if (editorArray[i] == null)
            {
                editorArray[i] = black;
                continue;
            }
            width = Mathf.Max(width, editorArray[i].width);
            height = Mathf.Max(height, editorArray[i].height);
        }

        if (width == 0) return;

        RenderTexture[] temp = new RenderTexture[editorArray.Length];
        Texture2D[] temp2 = new Texture2D[editorArray.Length];

        for (int i = 0; i < editorArray.Length; i++)
        {
            temp[i] = RenderTexture.GetTemporary(width, height);
            if (editorArray[i] != null)
            {
                Graphics.Blit(editorArray[i], temp[i]);
            }

            temp2[i] = new Texture2D(width, height, TextureFormat.RGBA32, false);
            RenderTexture.active = temp[i];
            temp2[i].ReadPixels(new Rect(0, 0, width, height), 0, 0);
            temp2[i].Apply();
            RenderTexture.ReleaseTemporary(temp[i]);
        }

        Texture2D final = new Texture2D(width, height, TextureFormat.RGBA32, false);
        float[] _cols = new float[4];

        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < height; j++)
            {
                for (int k = 0; k < 4; k++)
                {
                    switch (types[k])
                    {
                        case OPTIONS.R: _cols[k] = temp2[k].GetPixel(i, j).r; break;
                        case OPTIONS.G: _cols[k] = temp2[k].GetPixel(i, j).g; break;
                        case OPTIONS.B: _cols[k] = temp2[k].GetPixel(i, j).b; break;
                        case OPTIONS.A: _cols[k] = temp2[k].GetPixel(i, j).a; break;

                        case OPTIONS.R_G2L: _cols[k] = Mathf.GammaToLinearSpace(temp2[k].GetPixel(i, j).r); break;
                        case OPTIONS.G_G2L: _cols[k] = Mathf.GammaToLinearSpace(temp2[k].GetPixel(i, j).g); break;
                        case OPTIONS.B_G2L: _cols[k] = Mathf.GammaToLinearSpace(temp2[k].GetPixel(i, j).b); break;
                        case OPTIONS.A_G2L: _cols[k] = Mathf.GammaToLinearSpace(temp2[k].GetPixel(i, j).a); break;

                        case OPTIONS.R_L2G: _cols[k] = Mathf.LinearToGammaSpace(temp2[k].GetPixel(i, j).r); break;
                        case OPTIONS.G_L2G: _cols[k] = Mathf.LinearToGammaSpace(temp2[k].GetPixel(i, j).g); break;
                        case OPTIONS.B_L2G: _cols[k] = Mathf.LinearToGammaSpace(temp2[k].GetPixel(i, j).b); break;
                        case OPTIONS.A_L2G: _cols[k] = Mathf.LinearToGammaSpace(temp2[k].GetPixel(i, j).a); break;

                        case OPTIONS.R_INV: _cols[k] = 1.0f - temp2[k].GetPixel(i, j).r; break;
                        case OPTIONS.G_INV: _cols[k] = 1.0f - temp2[k].GetPixel(i, j).g; break;
                        case OPTIONS.B_INV: _cols[k] = 1.0f - temp2[k].GetPixel(i, j).b; break;
                        case OPTIONS.A_INV: _cols[k] = 1.0f - temp2[k].GetPixel(i, j).a; break;
                        case OPTIONS.Black: _cols[k] = 0; break;
                        case OPTIONS.Write: _cols[k] = 1f; break;
                    }
                }

                final.SetPixel(i, j, new Color(_cols[0], _cols[1], _cols[2], _cols[3]));
            }
        }

        final.Apply();
        for (int i = 0; i < editorArray.Length; i++)
        {
            GameObject.DestroyImmediate(temp2[i]);
        }

        byte[] date = TgaUtil.Texture2DEx.EncodeToTGA(final, true);
        System.IO.File.WriteAllBytes(savePath, date);
        GameObject.DestroyImmediate(final);
        GameObject.DestroyImmediate(black);

        // 保存后更新上次保存路径
        UpdateLastSavePath(savePath);
    }

    void CombineMesh2(string savePath)
    {
        Texture2D black = new Texture2D(1, 1, TextureFormat.RGBA32, false);
        black.SetPixel(0, 0, Color.black);
        black.Apply();

        int width = 0;
        int height = 0;
        for (int i = 0; i < editorArray.Length; i++)
        {
            if (editorArray[i] == null)
            {
                editorArray[i] = black;
                continue;
            }
            width = Mathf.Max(width, editorArray[i].width);
            height = Mathf.Max(height, editorArray[i].height);
        }

        if (width == 0) return;

        RenderTexture[] temp = new RenderTexture[editorArray.Length];
        Texture2D[] temp2 = new Texture2D[editorArray.Length];

        for (int i = 0; i < editorArray.Length; i++)
        {
            temp[i] = RenderTexture.GetTemporary(width, height);
            if (editorArray[i] != null)
            {
                Graphics.Blit(editorArray[i], temp[i]);
            }

            temp2[i] = new Texture2D(width, height, TextureFormat.RGBA32, false);
            RenderTexture.active = temp[i];
            temp2[i].ReadPixels(new Rect(0, 0, width, height), 0, 0);
            temp2[i].Apply();
            RenderTexture.ReleaseTemporary(temp[i]);
        }

        Texture2D final = new Texture2D(width, height, TextureFormat.RGBA32, false);
        float[] _cols = new float[4];

        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < height; j++)
            {
                for (int k = 0; k < 4; k++)
                {
                    switch (types[k])
                    {
                        case OPTIONS.R: _cols[k] = temp2[k].GetPixel(i, j).r; break;
                        case OPTIONS.G: _cols[k] = temp2[k].GetPixel(i, j).g; break;
                        case OPTIONS.B: _cols[k] = temp2[k].GetPixel(i, j).b; break;
                        case OPTIONS.A: _cols[k] = temp2[k].GetPixel(i, j).a; break;

                        case OPTIONS.R_G2L: _cols[k] = Mathf.GammaToLinearSpace(temp2[k].GetPixel(i, j).r); break;
                        case OPTIONS.G_G2L: _cols[k] = Mathf.GammaToLinearSpace(temp2[k].GetPixel(i, j).g); break;
                        case OPTIONS.B_G2L: _cols[k] = Mathf.GammaToLinearSpace(temp2[k].GetPixel(i, j).b); break;
                        case OPTIONS.A_G2L: _cols[k] = Mathf.GammaToLinearSpace(temp2[k].GetPixel(i, j).a); break;

                        case OPTIONS.R_L2G: _cols[k] = Mathf.LinearToGammaSpace(temp2[k].GetPixel(i, j).r); break;
                        case OPTIONS.G_L2G: _cols[k] = Mathf.LinearToGammaSpace(temp2[k].GetPixel(i, j).g); break;
                        case OPTIONS.B_L2G: _cols[k] = Mathf.LinearToGammaSpace(temp2[k].GetPixel(i, j).b); break;
                        case OPTIONS.A_L2G: _cols[k] = Mathf.LinearToGammaSpace(temp2[k].GetPixel(i, j).a); break;

                        case OPTIONS.R_INV: _cols[k] = 1.0f - temp2[k].GetPixel(i, j).r; break;
                        case OPTIONS.G_INV: _cols[k] = 1.0f - temp2[k].GetPixel(i, j).g; break;
                        case OPTIONS.B_INV: _cols[k] = 1.0f - temp2[k].GetPixel(i, j).b; break;
                        case OPTIONS.A_INV: _cols[k] = 1.0f - temp2[k].GetPixel(i, j).a; break;
                        case OPTIONS.Black: _cols[k] = 0; break;
                        case OPTIONS.Write: _cols[k] = 1f; break;
                        default: _cols[k] = temp2[k].GetPixel(i, j).a; break;
                    }
                }

                final.SetPixel(i, j, new Color(_cols[0], _cols[1], _cols[2], _cols[3]));
            }
        }

        final.Apply();
        for (int i = 0; i < editorArray.Length; i++)
        {
            GameObject.DestroyImmediate(temp2[i]);
        }

        byte[] date = final.EncodeToPNG();
        System.IO.File.WriteAllBytes(savePath, date);
        GameObject.DestroyImmediate(final);
        GameObject.DestroyImmediate(black);

        // 保存后更新上次保存路径
        UpdateLastSavePath(savePath);
    }

    bool AddUVToObject(string ObjPath, string CsvPath, int index0, int StartIndex)
    {
        char[] spes = new char[1] { '/' };
        char[] spesSp = new char[1] { ' ' };

        try
        {
            if (!System.IO.File.Exists(ObjPath))
            {
                Debug.Log("路径1[" + ObjPath + "]不存在");
                return false;
            }
            if (!System.IO.File.Exists(CsvPath))
            {
                Debug.Log("路径2[" + CsvPath + "]不存在");
                return false;
            }

            string[] lines = System.IO.File.ReadAllLines(ObjPath);
            string[] csvs = System.IO.File.ReadAllLines(CsvPath);
            List<string> finals = new List<string>();
            int index = 0;

            // 加入v
            for (; index < lines.Length; index++)
            {
                string line = lines[index];
                if (line.StartsWith("v "))
                {
                    finals.Add(line);
                }
                else
                {
                    break;
                }
            }

            // 跳过vt
            for (; index < lines.Length; index++)
            {
                string line = lines[index];
                if (line.StartsWith("vt "))
                {
                    // 跳过现有UV
                }
                else
                {
                    break;
                }
            }

            // 计算UV数量
            int count = 0;
            for (int i = 1; i < csvs.Length; i++)
            {
                string l1 = csvs[i];
                string[] arrays1 = l1.Split(',');
                if (arrays1[0] == "0")
                    count++;
                else
                    break;
            }

            // 加入新vt
            for (int i = 1; i < csvs.Length; i += count)
            {
                string l1 = csvs[i + StartIndex];
                string l2 = csvs[i + StartIndex + 1];
                string[] arrays1 = l1.Split(',');
                string[] arrays2 = l2.Split(',');
                string ps1 = arrays1[index0];
                string ps2 = arrays2[index0];

                double v = double.Parse(ps2);
                while (v > 1f)
                    v -= 1f;
                while (v < 0)
                    v += 1f;
                v = 1 - v;
                finals.Add("vt " + ps1 + " " + v);
            }

            // 加入vn
            for (; index < lines.Length; index++)
            {
                string line = lines[index];
                if (line.StartsWith("vn "))
                {
                    finals.Add(line);
                }
                else
                {
                    break;
                }
            }

            // 加入末尾
            for (; index < lines.Length; index++)
            {
                string line = lines[index];

                if (line.StartsWith("f "))
                {
                    string _l = "f ";
                    string[] _params = line.Split(spesSp, StringSplitOptions.RemoveEmptyEntries);
                    for (int j = 1; j < _params.Length; j++)
                    {
                        string _p = _params[j];
                        string[] _ps = _p.Split(spes, StringSplitOptions.RemoveEmptyEntries);
                        if (_ps.Length == 3)
                        {
                            _l += _p + " ";
                        }
                        else
                        {
                            _l += _ps[0] + "/" + _ps[0] + "/" + _ps[0] + " ";
                        }
                    }
                    finals.Add(_l);
                }
                else
                {
                    finals.Add(line);
                }
            }

            System.IO.File.WriteAllLines(ObjPath, finals);
            Debug.Log("合并完成");
            return true;
        }
        catch (Exception e)
        {
            Debug.Log("格式解析有错误: " + e.Message);
        }
        return false;
    }
}